package com.syezon.android.base.download;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.util.SparseArray;

import java.util.ArrayList;
import java.util.List;

public class DownloadInfoDao {

    private final SparseArray<DownloadInfo> downloadInfoMap = new SparseArray<>();
    private SQLiteDatabase mDataBase;

    public DownloadInfoDao(Context context) {
        DownloadOpenHelper downloadOpenHelper = new DownloadOpenHelper(context);
        mDataBase = downloadOpenHelper.getWritableDatabase();
        refreshDataFromDB();
    }

    private void refreshDataFromDB() {
        long start = System.currentTimeMillis();
        Cursor cursor = mDataBase.rawQuery("SELECT * FROM " + DownloadOpenHelper.TABLE_NAME, null);
        try {
            while (cursor.moveToNext()) {
                DownloadInfo downloadInfo = new DownloadInfo();
                downloadInfo.setDownloadId(cursor.getString(cursor.getColumnIndex(DownloadOpenHelper.ID)));
                downloadInfo.setTotalSize(cursor.getLong(cursor.getColumnIndex(DownloadOpenHelper.TOTAL_SIZE)));
                downloadInfo.setCompletedSize(cursor.getLong(cursor.getColumnIndex(DownloadOpenHelper.COMPLETED_SIZE)));
                downloadInfo.setSaveDirPath(cursor.getString(cursor.getColumnIndex(DownloadOpenHelper.SAVE_DIR_PATH)));
                downloadInfo.setUrl(cursor.getString(cursor.getColumnIndex(DownloadOpenHelper.URL)));
                downloadInfo.setFileName(cursor.getString(cursor.getColumnIndex(DownloadOpenHelper.FILENAME)));
                downloadInfo.setDownloadStatus(cursor.getInt(cursor.getColumnIndex(DownloadOpenHelper.DOWNLOAD_STATUS)));
                downloadInfoMap.put(downloadInfo.getDownloadId().hashCode(), downloadInfo);
            }
        } finally {
            cursor.close();
            long duration = System.currentTimeMillis() - start;
            Log.i("DownloadInfoDao", String.format("检索时间为：%d 毫秒", duration));
        }
    }

    /**
     * @param downloadId
     * @return
     */
    public DownloadInfo find(String downloadId) {
        return downloadInfoMap.get(downloadId.hashCode());
    }

    public List<DownloadInfo> findAll() {
        List<DownloadInfo> downloadInfos = null;
        if (downloadInfoMap != null && downloadInfoMap.size() > 0) {
            downloadInfos = new ArrayList<>();
            for (int i = 0; i < downloadInfoMap.size(); i++) {
                DownloadInfo downloadInfo = downloadInfoMap.valueAt(i);
                downloadInfos.add(downloadInfo);
            }
        }
        return downloadInfos;
    }

    public void insert(DownloadInfo downloadInfo) {
        downloadInfoMap.put(downloadInfo.getDownloadId().hashCode(), downloadInfo);
        mDataBase.insert(DownloadOpenHelper.TABLE_NAME, null, downloadInfoToContentValues(downloadInfo));
    }

    public void update(DownloadInfo downloadInfo) {
        if (downloadInfo == null) {
            return;
        }
        if (find(downloadInfo.getDownloadId()) != null) {
            // 替换
            downloadInfoMap.remove(downloadInfo.getDownloadId().hashCode());
            downloadInfoMap.put(downloadInfo.getDownloadId().hashCode(), downloadInfo);
            mDataBase.update(DownloadOpenHelper.TABLE_NAME, downloadInfoToContentValues(downloadInfo), DownloadOpenHelper.ID + " = ? ", new String[]{downloadInfo.getDownloadId()});
        } else {
            insert(downloadInfo);
        }
    }

    public void update(List<DownloadInfo> downloadInfos) {
        if (downloadInfos == null) {
            return;
        }
        mDataBase.beginTransaction();
        try {
            for (DownloadInfo downloadInfo : downloadInfos) {
                if (find(downloadInfo.getDownloadId()) != null) {
                    // replace
                    downloadInfoMap.remove(downloadInfo.getDownloadId().hashCode());
                    downloadInfoMap.put(downloadInfo.getDownloadId().hashCode(), downloadInfo);
                    mDataBase.update(DownloadOpenHelper.TABLE_NAME, downloadInfoToContentValues(downloadInfo), DownloadOpenHelper.ID + " = ? ",
                            new String[]{downloadInfo.getDownloadId()});
                } else {
                    // insert new one.
                    downloadInfoMap.put(downloadInfo.getDownloadId().hashCode(), downloadInfo);
                    mDataBase.insert(DownloadOpenHelper.TABLE_NAME, null, downloadInfoToContentValues(downloadInfo));
                }
            }
            mDataBase.setTransactionSuccessful();
        } finally {
            mDataBase.endTransaction();
        }
    }


    public boolean remove(String downloadId) {
        downloadInfoMap.remove(downloadId.hashCode());
        return mDataBase.delete(DownloadOpenHelper.TABLE_NAME, DownloadOpenHelper.ID + " = ?", new String[]{downloadId}) != 0;
    }

    public boolean remove(DownloadInfo downloadInfo) {
        downloadInfoMap.remove(downloadInfo.getDownloadId().hashCode());
        return mDataBase.delete(DownloadOpenHelper.TABLE_NAME, DownloadOpenHelper.ID + " = ?", new String[]{downloadInfo.getDownloadId()}) != 0;
    }

    public void clear() {
        downloadInfoMap.clear();
        mDataBase.delete(DownloadOpenHelper.TABLE_NAME, null, null);
    }

    public void closeDao() {
        if (mDataBase != null && mDataBase.isOpen()) {
            mDataBase.close();
        }
    }

    private ContentValues downloadInfoToContentValues(DownloadInfo downloadInfo) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(DownloadOpenHelper.ID, downloadInfo.getDownloadId());
        contentValues.put(DownloadOpenHelper.COMPLETED_SIZE, downloadInfo.getCompletedSize());
        contentValues.put(DownloadOpenHelper.TOTAL_SIZE, downloadInfo.getTotalSize());
        contentValues.put(DownloadOpenHelper.SAVE_DIR_PATH, downloadInfo.getSaveDirPath());
        contentValues.put(DownloadOpenHelper.URL, downloadInfo.getUrl());
        contentValues.put(DownloadOpenHelper.FILENAME, downloadInfo.getFileName());
        contentValues.put(DownloadOpenHelper.DOWNLOAD_STATUS, downloadInfo.getDownloadStatus());
        return contentValues;
    }
}
